home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / qrymod / d_integ.c next >
Encoding:
C/C++ Source or Header  |  1988-05-30  |  5.3 KB  |  240 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <catalog.h>
  4. # include    <tree.h>
  5. # include    <symbol.h>
  6. # include    <pv.h>
  7. # include    <resp.h>
  8. # include    <func.h>
  9. # include    "qrymod.h"
  10. # include    <sccs.h>
  11. # include    <errors.h>
  12.  
  13. SCCSID(@(#)d_integ.c    8.4    5/30/88)
  14.  
  15.  
  16. /*
  17. **  D_INTEG -- define integrity constraint
  18. **
  19. **    An integrity constraint (as partially defined by the last
  20. **    tree defined by d_tree) is defined.
  21. **
  22. **    Parameters:
  23. **        none
  24. **
  25. **    Returns:
  26. **        none
  27. **
  28. **    Side Effects:
  29. **        Activity in 'relation' and 'integrities' catalogs.
  30. **
  31. **    Trace Flags:
  32. **        49
  33. */
  34.  
  35. extern DESC    Intdes;
  36. extern DESC    Reldes;
  37.  
  38. extern        d_integ(), null_fn();
  39. extern short    tTqm[80];
  40.  
  41. struct fn_def    DefIntFn =
  42. {
  43.     "DINTEG",
  44.     d_integ,
  45.     null_fn,
  46.     null_fn,
  47.     NULL,
  48.     0,
  49.     tTqm,
  50.     80,
  51.     'Q',
  52.     0
  53. };
  54.  
  55.  
  56.  
  57. d_integ(pc, pv)
  58. int    pc;
  59. PARM    *pv;
  60. {
  61.     register int        i;
  62.     register QTREE        *t;        /* definition tree */
  63.     struct integrity    inttup;
  64.     struct tup_id        tid;
  65.     register int        rv;        /* result variable */
  66.     struct relation        relkey;
  67.     struct relation        reltup;
  68.     char            relid[MAXNAME];
  69.     char            relowner[2];
  70.     long            relstat;
  71.     struct    qthdr        qt;
  72.  
  73.     if (pv[0].pv_type != PV_QTREE)
  74.         syserr("d_integ: tree");
  75.     t = pv[0].pv_val.pv_qtree;
  76.     rv = Qt.qt_resvar;
  77.  
  78.     /*
  79.     **  Check for valid environment.
  80.     **    The tree must exist, have a qualification, and have
  81.     **    no target list.  The query mode must be mdINTEG.
  82.     **
  83.     **    User level stuff checks to see that this is single
  84.     **    variable aggregate free, since that's all we know
  85.     **    about thusfar.  Also, the relation in question must
  86.     **    not be a view.
  87.     */
  88.  
  89. #    ifdef xQTR3
  90.     if (t == NULL)
  91.         syserr("d_integ: NULL tree");
  92.     if ((i = t->right->sym.type) != AND)
  93.         syserr("d_integ: qual %d", i);
  94.     if ((i = t->left->sym.type) != TREE)
  95.         syserr("d_integ: TL %d", i);
  96.     if (Qt.qt_qmode != mdINTEG)
  97.         syserr("d_integ: Qmode %d", Qt.qt_qmode);
  98. #    endif
  99.     
  100.     /* check for aggregates */
  101.     if (aggcheck(t))
  102.         qmerror(NOAGGINT, -1, rv, 0);    /* aggregates in qual */
  103.  
  104.     /* check for multi-variable */
  105.     for (i = 0; i < MAXRANGE; i++)
  106.     {
  107.         if (Qt.qt_rangev[i].rngvdesc == NULL)
  108.             continue;
  109.         if (i != rv)
  110.         {
  111. #            ifdef xQTR3
  112.             if (tTf(49, 1))
  113.                 printf("d_integ: Rv %d(%.14s) i %d(%.14s)\n",
  114.                     rv, Qt.qt_rangev[rv].rngvdesc->reldum.relid,
  115.                     i, Qt.qt_rangev[i].rngvdesc->reldum.relid);
  116. #            endif
  117.             qmerror(NOMULTIVAR, -1, rv, 0);    /* too many vars */
  118.         }
  119.     }
  120.  
  121.  
  122.     /* check for the resultvariable being a real relation */
  123.     if (bitset(S_VIEW, Qt.qt_rangev[rv].rngvdesc->reldum.relstat))
  124.         qmerror(INTVIEW, -1, rv, 0);    /* is a view */
  125.     
  126.     /* guarantee that you own this relation */
  127.     if (!bequal(Usercode, Qt.qt_rangev[rv].rngvdesc->reldum.relowner, UCODE_SZ))
  128.         qmerror(MUSTOWN, -1, rv, 0);    /* don't own reln */
  129.     bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relid, relid, MAXNAME);
  130.     bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relowner, relowner, 2);
  131.     bmove(&Qt,&qt, sizeof (Qt));
  132.     relstat = Qt.qt_rangev[rv].rngvdesc->reldum.relstat;
  133.  
  134.     /*
  135.     **  Guarantee that the integrity constraint is true now.
  136.     **    This involves issuing a retrieve statement for the
  137.     **    inverse of the qualification.  The target list is
  138.     **    already null, so we will get nothing printed out
  139.     **    (only a return status).
  140.     **
  141.     **    We reset resp_tups if ok so that the user isn't annoyed
  142.     **    by a tuple count.  On error, it is a count of the
  143.     **    number of tuples that don't satisfy.
  144.     */
  145.  
  146.     Qt.qt_qmode = mdRETR;
  147.     Qt.qt_resvar = -1;
  148.  
  149.     /* issue the invert of the query */
  150.     issueinvert(t);
  151.     if (Resp.resp_tups != 0)
  152.         qmerror(INITCONST, -1, rv, 0);    /* constraint not satisfied */
  153.     Resp.resp_tups = -1;
  154.     bmove(&qt,&Qt, sizeof (Qt));
  155.  
  156.     /*
  157.     **  Set up the rest of the environment.
  158.     */
  159.  
  160.     opencatalog("integrities", OR_WRITE);
  161.     clr_tuple(&Intdes, &inttup);
  162.     Qt.qt_resvar = -1;
  163.     Qt.qt_qmode = -1;
  164.  
  165.     /*
  166.     **  Set up integrity relation tuple.
  167.     **    The qualification will be scanned, and a set of
  168.     **    domains referenced will be created.  Other stuff
  169.     **    is filled in from the range table and from the
  170.     **    parser.
  171.     **
  172.     **    The tree is actually inserted into the tree catalog
  173.     **    in this step.  Extra information is cleared here.
  174.     */
  175.  
  176.     inttup.intresvar = rv;
  177.     bmove(relid, inttup.intrelid, MAXNAME);
  178.     bmove(relowner, inttup.intrelowner, 2);
  179.     makeidset(rv, t, inttup.intdomset);
  180.     inttup.inttree = puttree(t, inttup.intrelid, inttup.intrelowner, mdINTEG);
  181.  
  182.     /*
  183.     **  Insert tuple into integrity catalog.
  184.     */
  185.  
  186.     i = insert(&Intdes, &tid, &inttup, FALSE);
  187.     if (i < 0)
  188.         syserr("d_integ: insert");
  189.     if (noclose(&Intdes) != 0)
  190.         syserr("d_integ: noclose int");
  191.  
  192.     /*
  193.     **  Update relstat S_INTEG bit.
  194.     */
  195.  
  196.     if (!bitset(S_INTEG, relstat))
  197.     {
  198.         opencatalog("relation", OR_WRITE);
  199.         clearkeys(&Reldes);
  200.         setkey(&Reldes, &relkey, inttup.intrelid, RELID);
  201.         setkey(&Reldes, &relkey, inttup.intrelowner, RELOWNER);
  202.         i = getequal(&Reldes, &relkey, &reltup, &tid);
  203.         if (i != 0)
  204.             syserr("d_integ: geteq returns %d",i);
  205.         reltup.relstat |= S_INTEG;
  206.         i = replace(&Reldes, &tid, &reltup, FALSE);
  207.         if (i != 0)
  208.             syserr("d_integ: replace returns %d",i);
  209.         if (noclose(&Reldes) != 0)
  210.             syserr("d_integ: noclose rel");
  211.     }
  212.  
  213.     return (0);
  214. }
  215.  
  216.  
  217. makeidset(varno, tree, dset)
  218. int    varno;
  219. QTREE    *tree;
  220. short    dset[8];
  221. {
  222.     register int    vn;
  223.     register QTREE    *t;
  224.  
  225.     vn = varno;
  226.     t = tree;
  227.  
  228.     while (t != NULL)
  229.     {
  230.         if (t->sym.type == VAR && t->sym.value.sym_var.varno == vn)
  231.             lsetbit(t->sym.value.sym_var.attno, dset);
  232.         
  233.         /* handle left subtree recursively */
  234.         makeidset(vn, t->left, dset);
  235.  
  236.         /* handle right subtree iteratively */
  237.         t = t->right;
  238.     }
  239. }
  240.